package com.yanqu.road.entity.event;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class GameEvent implements IEvent {

    private static Logger logger = LogManager.getLogger(GameEvent.class.getName());

    private ReadWriteLock lock;
    private HashMap<Integer, Collection<IEventListener>> eventMap;

    public GameEvent() {
        super();
        eventMap = new HashMap<>();
        lock = new ReentrantReadWriteLock(false);
    }


    @Override
    public void addListener(int eventCode, IEventListener listener) {
        lock.writeLock().lock();

        Collection<IEventListener> listListeners = eventMap.get(eventCode);
        if (null == listListeners) {
            listListeners = Collections.synchronizedSet(new HashSet<>());
            eventMap.put(eventCode, listListeners);
        }

        if (!listListeners.contains(listener)) {
            listListeners.add(listener);
        }

        lock.writeLock().unlock();
    }

    @Override
    public void removeListener(int eventCode, IEventListener listener) {
        lock.writeLock().lock();

        Collection<IEventListener> listListeners = eventMap.get(eventCode);
        if (listListeners != null && listListeners.contains(listener)) {
            listListeners.remove(listener);
        }

        lock.writeLock().unlock();
    }

    @Override
    public boolean notifyListener(int eventCode) {
        lock.readLock().lock();

        List<IEventListener> eventListenerList = null;
        if(eventMap.containsKey(eventCode)){
            eventListenerList = new ArrayList<>(eventMap.get(eventCode));
        }

        lock.readLock().unlock();

        if (null != eventListenerList) {
            for (IEventListener iEventListener : eventListenerList) {
                try {
                    iEventListener.triggerEvent(new EventTriggerArgs(this));
                } catch (Exception ex) {
                    logger.error("事件触发异常 :" + iEventListener.getClass(), ex);
                }
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean notifyListener(int eventCode, EventTriggerArgs eventArg) {
        lock.readLock().lock();
        List<IEventListener> eventListenerList = null;
        if(eventMap.containsKey(eventCode)){
            eventListenerList = new ArrayList<>(eventMap.get(eventCode));
        }
        lock.readLock().unlock();

        if (null != eventListenerList) {
            for (IEventListener iEventListener : eventListenerList) {
                try {
                    iEventListener.triggerEvent(eventArg);
                } catch (Exception ex) {
                    logger.error("事件触发异常 :" + iEventListener.getClass(), ex);
                }
            }
            return true;
        }
        return false;
    }
}
